import numpy as np
from math import sqrt
from collections import Counter

# 参考波波老师的代码，用到了Python中的math和collections.Counter来完成统计操作
def kNN_classify1(k, X_train, y_train, a):
    assert 1 <= k <= X_train.shape[0], "k值必须大于等于0，并且小于等于训练样本个数"
    assert X_train.shape[0] == y_train.shape[0], "训练样本个数必须和类型数相等"
    assert X_train.shape[1] == a.shape[0], "待预测的样本特征数必须和训练样本的特征数相等"

    # 计算样本a到每一个训练样本的距离
    distances = [sqrt(np.sum((a - x) ** 2)) for x in X_train]
    # 将样本a到各个训练样本的距离进行排序，获取排序后每个距离在原训练样本中的索引
    nearestDisIndexes = np.argsort(distances)

    # 获取距离样本a最近的k个样本的类型
    topK_y = [y_train[i] for i in nearestDisIndexes[:k]]

    # 统计不同类型的个数
    votes = Counter(topK_y)

    # 返回 距离样本a最近的 k个样本中 出现次数最多的类型 作为KNN算法预测的结果
    return votes.most_common(1)[0][0]